<template>
  <div class="erp-form-modal">
    <el-input
      :placeholder="inputPlaceholder"
      :value="selectName"
      :readonly="readonly"
      @input="handleInput"
    >
      <div
        v-if="selectName"
        slot="suffix"
        class="icon-class"
      >
        <i
          class="el-icon-close clear-icon"
          @click="handleClear"
        />
      </div>
      <div
        slot="append"
        style="cursor:pointer;margin-right:5px;display: block"
        @click="handleModal"
      >
        选择
      </div>
    </el-input>
    <vxe-modal
      v-if="extra.modalShow"
      ref="modal"
      v-model="extra.modalShow"
      class="vxe-table--ignore-clear erp-form-modal-modal"
      :title="title"
      :show-footer="true"
      :resize="true"
      :transfer="true"
      :width="modalWidth"
      :height="modalHeight"
      :z-index="1300"
      @close="handleCloseModal"
      @zoom="handleZoom"
    >
      <template #default>
        <div class="erp-form-modal-body">
          <div
            v-if="multiple"
            class="erp-form-modal-selected shadow"
          >
            <div class="selected-box">
              <div class="selected-title">
                已选择项
                <span
                  class="clear-all-selected"
                  @click="clearAllSelection"
                >
                  清空
                </span>
                <el-button
                  style=""
                  type="text"
                />
              </div>
              <div class="selected-body">
                <div v-if="selectedList && selectedList.length > 0">
                  <div
                    v-for="(item,index) in selectedList"
                    :key="index"
                    class="selected-item"
                    @click="handleClearItem(item, index)"
                  >
                    <span>{{ item[modelNameField] }}</span>
                    <i class="el-icon-close" />
                  </div>
                </div>
                <div v-else>
                  暂未选择选项
                </div>
              </div>
            </div>
          </div>
          <div
            ref="modalList"
            class="erp-form-modal-list"
            :class="{single:!multiple}"
            style="padding: 15px;box-sizing: border-box"
          >
            <div style="background-color: #fff;height: 100%">
              <erp-list-page
                v-if="options"
                ref="erpListPage"
                :options.sync="computedOptions"
                :multiple-selected-ids="multiple ? multipleSelectedIds: []"
                :extra-data="form"
                @single-select-close="handleSingleSelectClose"
                @multiple-select-change="handleMultipleSelectChange"
                @multiple-select-all-change="handleMultipleSelectAllChange"
                @list-change="handleDataChange"
                @change-options="handleChangeOptions"
              />
            </div>
          </div>
        </div>
      </template>

      <template slot="footer">
        <slot name="footer-append" />
        <el-button
          v-if="multiple"
          type="primary"
          :loading="saveLoading"
          @click="handleSaveModal"
        >
          {{ $t('common.confirm') }}
        </el-button>
        <el-button
          class="close"
          @click="handleCloseModal"
        >
          {{ $t('common.close') }}
        </el-button>
      </template>
    </vxe-modal>
  </div>
</template>

<script>
import Vue from 'vue';
import {Input} from "element-ui";
import {cloneJson, uniqueArray, toString} from "@/utils";

const ErpListPage = () => import("@/components/erp03/ErpListPage/ErpListPage");
Vue.use(Input);
/**
 * 模态框组件
 * @author maolin
 */
export default {
  name: "ErpFormModal01",
  components: {
    ErpListPage,
  },
  model:{
    prop: 'value',
    event: "value-change"
  },
  props: {
    /**
     * 标题
     * @public
     */
    title: {
      type: String,
      default: '',
    },
    /**
     * 字段
     * @public
     */
    field: {
      type: String,
      default: ''
    },
    /**
     * 值
     * @public
     */
    value: {
      type: [Number, String, Array, Object],
      default: null
    },
    /**
     * 属性
     * @public
     */
    props: {
      type: Object,
      default () {
        return {
        };
      }
    },
    /**
     * 选项
     * @public
     */
    options: {
      type: Object,
    },
    /**
     * 额外配置
     * ```js
     * return {
          idField: '',
          inputPlaceholder: '',
          modalTitle: '',
          modalWidth: null,
          modalHeight: null,
          modalNameField: null,
          modalIdField: null,
          needToString: false,
          // 关联额外字段，除了id和name之外还需要关联字段时
          extraData: [
            {
              // 外部id
              field: "userId",
              // 内部id
              relatedField: "id",
            }
          ]
        }
     * ```
     * @public
     */
    extra: {
      type: Object,
      default () {
        return {
          idField: '',
          inputPlaceholder: '',
          modalTitle: '',
          modalWidth: null,
          modalHeight: null,
          modalNameField: null,
          modalIdField: null,
          needToString: false,
          modalShow:false,
          // 关联额外字段，除了id和name之外还需要关联字段时
          extraData: [
            {
              // 外部id
              field: "userId",
              // 内部id
              relatedField: "id",
            }
          ]
        };
      }
    },
    /**
     * 表单对象
     * @public
     */
    form: {
      type: Object,
      default () {
        return {};
      }
    }
  },
  data () {
    return {
      tableHeight: 0,
      loading: false,
      visibleDialog: true,
      fullscreen: false,
      saveLoading: false,
      checkedList: null,
      tableList: [],
      selectedIds: []
    };
  },
  computed: {
    extraData () {
      return this.extra && this.extra.extraData ?   this.extra.extraData :[];
    },
     hiddenFormItem () {
      return function (item) {
        if (item.visibleFunction) {
          try{
            return new Function('form','field', 'query', item.visibleFunction )(this.form, item.field, this.query);
          }catch(e) {
            console.log('visibleFunction error');
            console.log(e);
          }
        }
        return true;
      };
    },
    computedOptions:{
      get() {
        let options = cloneJson(this.options);
        options.table.height = this.tableHeight;
        if (this.multiple) {
          options.type = 'multipleSelect';
          options.table.selectable = true;
        } else {
          options.type = 'singleSelect';
          options.table.selectable = false;
        }
        return options;
      },
      set (val) {
        this.$emit('update:options', val);
      }
    },
    inputPlaceholder() {
      if (this.extra && this.extra.inputPlaceholder) {
        return this.extra.inputPlaceholder;
      }
      return '请选择';
    },
    selectedList: {
      set (val) {
        this.checkedList = val;
      },
      get () {
        let ids = this.defaultIdsValue;
        let checkedList = this.checkedList;
        let check = [];
        if (checkedList === null) {
          if (ids) {
            if (typeof ids === 'number') {
              ids = toString(ids);
            }
            ids = ids ? ids.split(',') : [];
            let names = this.value ? this.value.split(',') : [];
            if (ids && ids.length > 0) {
              for(let i in ids) {
                check.push({
                  [this.modelIdField]: ids[i],
                  [this.modelNameField]: names[i]
                });
              }
            }
          }
        } else {
          check = checkedList;
        }
        let data = this.tableList;
        let modelIdField = this.modelIdField;
        return check.map((item) => {
          if (data && data.length > 0) {
            for (let i in data) {
              if (data[i][modelIdField] == item[modelIdField]) {
                return data[i];
              }
            }
          }
          return item;
        });
      }
    },
    suffixIcon () {
      let suffixIcon = "el-icon-more";
      if (this.extra && this.extra.suffixIcon) {
        suffixIcon = this.extra.suffixIcon;
      }
      return suffixIcon;
    },
    defaultIdsValue () {
      let form = this.form;
      let idField = this.idField;
      return form && idField && form[idField] !== undefined ? form[idField] : '';
    },
    multipleSelectedIds () {
      let selectedList = this.selectedList;
      let array = [];
      if (selectedList && selectedList.length > 0) {
        for (let i in selectedList) {
          array.push(selectedList[i][this.modelIdField]);
        }
      }
      return array;
    },
    idField () {
      let idField = null;
      if (this.extra && this.extra.idField) {
        idField = this.extra.idField;
      }
      return idField;
    },
    readonly () {
      let readonly = true;
      if (this.extra && this.extra.readonly === false) {
        readonly = false;
      }
      return readonly;
    },
    selectName: {
      get () {
        return this.value;
      },
      set (value) {
        this.$emit('value-change', value);
      }
    },
    modalTitle () {
      return this.extra && this.extra.modalTitle ?  this.extra.modalTitle : this.$t('common.select');
    },
    modalWidth () {
      return this.extra && this.extra.modalWidth ?  this.extra.modalWidth : '80%';
    },
    modalHeight () {
      return this.extra && this.extra.modalHeight ?  this.extra.modalHeight : '';
    },
    modelIdField () {
      return this.extra && this.extra.modalIdField ?  this.extra.modalIdField : null;
    },
    modelNameField () {
      return this.extra && this.extra.modalNameField ?  this.extra.modalNameField : null;
    },
    multiple () {
      return !!(this.extra && this.extra.multiple);
    },
    needToString () {
      return !!(this.extra && this.extra.needToString);
    }
  },
  watch: {
    defaultIdsValue (defaultIdsValue) {
      this.selectedIds = toString(defaultIdsValue) ? (toString(defaultIdsValue)).split(',') : [];
    },
  },
  methods: {
    visibleFunc (item, query) {
      if (item.visibleFunction) {
        let form = this.form;
        let field = item.field;
        try{
          return new Function('form','field', 'query', item.visibleFunction )(form, field, query);
        }catch(e) {
          return true;
        }
      }
      return true;
    },
    /**
     * 更新列表的配置
     * @private
     * @param options 列表配置
     */
    handleChangeOptions (options) {
      this.computedOptions = options;
    },
    /**
     * 监听输入框
     * @private
     * @param {string} e 输入框的值
     */
    handleInput (e) {
      this.selectName = e;
      this.idField && this.updateIdField(this.idField, null);
    },
    /**
     * 进入全屏
     * @public
     */
    handleFullscreen () {
      this.fullscreen = true;
    },
    /**
     * 列表数据更新
     * @private
     * @param {array} data 列表数据
     */
    handleDataChange (data) {
      this.tableList = data;
    },
    /**
     * 退出全屏
     * @public
     */
    exitFullscreen () {
      this.fullscreen = false;
    },
    /**
     * 更新表单其他字段值
     * @private
     * @param field
     * @param val
     */
    updateIdField (field, val) {
      if (this.needToString) {
        val = toString(val);
      }
      /**
       * 更新表单其他字段值
       */
      this.$emit('update-id-field', {[field]: val});
    },
    /**
     * 打开模态框
     * @private
     */
    handleModal () {
      this.extra.modalShow = true;
    },
    /**
     * 关闭模态框
     * @private
     */
    handleCloseModal () {
      this.extra.modalShow = false;
    },
    /**
     * 保存模态框
     * @private
     */
    handleSaveModal () {
      let checkedList = this.checkedList;
      let ids = [];
      let names = [];
      if (checkedList && checkedList.length > 0) {
        for (let i in checkedList) {
          if (this.modelIdField) {
            ids.push(checkedList[i][this.modelIdField]);
          }
          if (this.modelNameField) {
            names.push(checkedList[i][this.modelNameField]);
          }
        }
      }
      names = names.join(',');
      ids = ids.join(',');
      this.updateIdField(this.idField, ids);
      this.selectName = names;
      this.handleCloseModal();
    },
    /**
     * 移除选中项
     * @private
     * @param {object} item 表格选中项
     * @param {number} index 选中项的索引
     */
    handleClearItem (item, index) {
      let selectedList = this.selectedList;
      selectedList.splice(index, 1);
      this.selectedList = selectedList;
      this.$refs.erpListPage.$refs.erpPageTable.$refs.table.$refs.erpTable.toggleCheckboxRow(item);
    },
    /**
     * 移除所有选中项
     * @private
     */
    clearAllSelection () {
      this.checkedList = [];
      this.$refs.erpListPage.$refs.erpPageTable.$refs.table.$refs.erpTable.clearSelection();
    },
    /**
     * 更新表单的其他值
     * @private
     */
    handleClear () {
      if (this.modelIdField) {
        this.updateIdField(this.idField, null);
      }
      if (this.extraData && this.extraData.length > 0) {
        for (let i in this.extraData) {
          this.updateIdField(this.extraData[i].field, null);
        }
      }
      this.selectName = "";
      this.handleCloseModal();
    },
    /**
     * 触发单选
     * @private
     * @param {object} data 选中的数据{item}
     */
    handleSingleSelectClose (data) {
      let item = data.item;
      this.$store.dispatch('erp/GetSourceOrderNoId', item.id);
      if (this.modelIdField) {
        this.updateIdField(this.idField, item[this.modelIdField] || null);
      }
      if (this.extraData && this.extraData.length > 0) {
        for (let i in this.extraData) {
          this.updateIdField(this.extraData[i].field, item[this.extraData[i].relatedField] || null);
        }
      }
      if (this.modelNameField) {
        this.selectName = item[this.modelNameField] || null;
      }
      this.handleCloseModal();
    },
    /**
     * 多选
     * @private
     * @param {object} data 选中的多条数据{selection}
     */
    handleMultipleSelectChange (data) {
      let checked = false;
      if (data.selection && data.selection.length > 0) {
        for (let i in data.selection) {
          if (data.selection[i][this.modelIdField] == data.row[this.modelIdField]) {
            checked = true;
            break;
          }
        }
      }
      this.selectedIds = [data.row[this.modelIdField]];
      this.multipleSelectChange([data.row], checked);
    },
    /**
     * 多选全选
     * @private
     * @param {object} data 选中的多条数据{selection}
     */
    handleMultipleSelectAllChange (data) {
      let checked = false;
      let list = cloneJson(this.tableList);
      if (data.selection && data.selection.length > 0) {
        checked = true;
        list = data.selection;
      }
      this.multipleSelectChange(list, checked);
    },
    /**
     * 缩放模态框
     * @private
     */
    handleZoom () {

    },
    /**
     * 勾选多选复选框触发
     * @private
     * @param {array} data 当前勾选的数据
     * @param {boolean} checked 是否选中
     */
    multipleSelectChange (data, checked) {
      let idField = this.modelIdField;
      let checkedList = cloneJson(this.selectedList);
      if (idField && data && data.length > 0) {
        if (checked) {
          checkedList = checkedList.concat(data);
          let obj = {};
          checkedList = checkedList.reduce((cur, next) => {
            obj[next[idField]] ? "" : obj[next[idField]] = true && cur.push(next);
            return cur;
          }, []);
        } else {
          let newCheckedList = [];
          for (let i in checkedList) {
            let isDelete = false;
            for (let j in data) {
              if (checkedList[i][idField] === data[j][idField]) {
                isDelete = true;
                break;
              }
            }
            if (!isDelete) {
              newCheckedList.push(checkedList[i]);
            }
          }
          checkedList = newCheckedList;
        }
      }
      this.selectedList = checkedList;
    }
  }
};
</script>

<style lang="scss" scoped>
    $primaryColor: var(--primary-color);
    .erp-form-modal-body{
        background-color: #fff;
        height: 100%;
        display: flex;
        flex-wrap: nowrap;
        justify-content: space-between;
        .erp-form-modal-modal{
            ::v-deep{
                .vxe-modal--box .vxe-modal--footer {
                    background-color: #f6f7f9;
                }
            }
        }
        .erp-form-modal-selected{
            width: 250px;
            padding: 15px;
            .selected-box{
                border-radius: 2px;
                background-color: #fff;
                height: 100%;
                .selected-title{
                    padding: 0 15px;
                    border-bottom: 1px solid #eee;
                    height: 40px;
                    line-height: 40px;
                    font-size: 14px;
                    font-weight: bold;
                    .clear-all-selected{
                        cursor: pointer;
                        user-select: none;
                    }

                }
                .selected-body{
                    height: calc(100% - 40px);
                    padding: 15px;
                    overflow-y: auto;
                    .selected-item{
                        cursor: pointer;
                        padding: 0 10px;
                        float:left;
                        height: 26px;
                        line-height: 26px;
                        border-radius: 2px;
                        margin-right: 10px;
                        margin-bottom: 10px;
                        background-color: #eee;
                        color: #000;
                        box-sizing: border-box;
                        border: 1px solid #eee;
                        user-select: none;
                        &:hover{
                            border: 1px solid $primaryColor;
                            color: $primaryColor;
                        }
                    }
                }
            }
        }
        .erp-form-modal-list{
            width:calc(100% - 250px);
            height: 100%;
            &.single{
                width: 100%;
            }
        }
    }
    ::v-deep{
        .el-input-group__append, .el-input-group__prepend{
            padding: 0 10px;
        }

    }
    .icon-class{
        height: 100%;
        position: relative;
        .clear-icon{
            position: absolute;
            top: 50%;
            left: -15px;
            transform: translateY(-50%);
        }
    }
</style>
